﻿using System;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using System.Drawing;

namespace AlgorithmCalculator
{
    public partial class MainForm : Form
    {
        string strHex;
        StringBuilder sbHexFormat = new StringBuilder();

        public MainForm()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            progressBar1.Value = 0;

            if (tabControl1.SelectedTab == tabPage1) //计算“十六进制字符串”
            {
                string strText = richTextBox1.Text.Replace(" ", string.Empty); //删除输入框中的所有空格
                if (strText.Length == 0)
                {
                    MessageBox.Show("请输入有效的十六进制字符串！");
                    return;
                }

                sbHexFormat.Remove(0, sbHexFormat.Length);
                int iLen = strText.Length;
                if (strText.Length % 2 != 0) //当输入的十六进制字符数量不够凑成一对，需要在前面补0
                {
                    sbHexFormat.Append("0");
                    iLen++;
                }
                sbHexFormat.Append(strText);

                for (int i = iLen - 2; i > 0; i -= 2) //两个十六进制字符为一组，用空格隔开
                {
                    sbHexFormat.Insert(i, ' ');
                }
                string[] hexValuesSplit = sbHexFormat.ToString().Split(' ');
                byte[] data = new byte[hexValuesSplit.Length];
                for (int i = 0; i < hexValuesSplit.Length; i++)
                {
                    data[i] = Convert.ToByte(hexValuesSplit[i], 16);
                }

                richTextBox2.Text = "原十六进制字符串： ";
                richTextBox2.Text += sbHexFormat.ToString();
                richTextBox2.Text += "\n";

                if (checkBox1.Enabled == true && checkBox1.Checked == true) //“累加和”勾选
                {
                    byte ResultCumulativeSum = 0;
                    foreach (byte item in data)
                    {
                        ResultCumulativeSum += item;
                    }
                    richTextBox2.Text += "累加和 ： ";
                    richTextBox2.Text += ResultCumulativeSum.ToString("X2");
                    richTextBox2.Text += "\n";
                }
                if (checkBox2.Enabled == true && checkBox2.Checked == true) //“异或和”勾选
                {
                    byte ResultXor = 0;
                    foreach (byte item in data)
                    {
                        ResultXor ^= item;
                    }
                    richTextBox2.Text += "异或和 ： ";
                    richTextBox2.Text += ResultXor.ToString("X2");
                    richTextBox2.Text += "\n";
                }
                if (checkBox3.Enabled == true && checkBox3.Checked == true) //“CRC16”勾选
                {
                    ushort ResultCRC16 = 0xFFFF;

                    //采用的参数模型：CRC-16/MODBUS
                    //其他CRC16的参数模型：CRC-16/IBM、CRC-16/MAXIM、CRC-16/USB、CRC-16/CCITT、CRC-16/CCITT-FALSE、CRC-16/X25、CRC-16/XMODEM、CRC-16/DNP
                    if (data.Length > 0)
                    {
                        for (int i = 0; i < data.Length; i++)
                        {
                            ResultCRC16 = (ushort)(ResultCRC16 ^ data[i]);
                            for (int j = 0; j < 8; j++)
                            {
                                ResultCRC16 = (ResultCRC16 & 1) != 0 ? (ushort)((ResultCRC16 >> 1) ^ 0xA001) : (ushort)(ResultCRC16 >> 1);
                            }
                        }
                    }
                    richTextBox2.Text += "CRC16  ： ";
                    richTextBox2.Text += ResultCRC16.ToString("X");
                    richTextBox2.Text += "\n";
                }
                if (checkBox4.Enabled == true && checkBox4.Checked == true) //“CRC32”勾选
                {
                    richTextBox2.Text += "CRC32  ： ";
                    richTextBox2.Text += CRC32.GetStringCRC32(data);
                    richTextBox2.Text += "\n";
                }
                if (checkBox5.Enabled == true && checkBox5.Checked == true) //“MD5”勾选
                {
                    //byte[] data = Encoding.GetEncoding("utf-8").GetBytes(richTextBox1.Text);
                    MD5 md5 = new MD5CryptoServiceProvider();
                    richTextBox2.Text += "MD5    ： ";
                    richTextBox2.Text += System.BitConverter.ToString(md5.ComputeHash(data)).Replace("-", "");
                    richTextBox2.Text += "\n";
                }
                if (checkBox6.Enabled == true && checkBox6.Checked == true) //“SHA1”勾选
                {
                    //byte[] data = Encoding.GetEncoding("utf-8").GetBytes(richTextBox1.Text);
                    SHA1 sha = new SHA1CryptoServiceProvider();
                    richTextBox2.Text += "SHA1   ： ";
                    richTextBox2.Text += System.BitConverter.ToString(sha.ComputeHash(data)).Replace("-", "");
                    richTextBox2.Text += "\n";
                }
            }
            else if (tabControl1.SelectedTab == tabPage2) //计算“文件”
            {
                if (textBox1.Text == "" || textBox1.Text == null)
                {
                    MessageBox.Show("请选择要计算的文件！");
                    return;
                }
                if (File.Exists(textBox1.Text) == false)
                {
                    MessageBox.Show("选中的文件不存在！");
                    return;
                }

                try
                {
                    new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                catch //(Exception ex)
                {
                    // throw ex;
                    // throw (new ApplicationException("文件打开失败！"));
                    MessageBox.Show("文件打开失败！");
                    return;
                }

                richTextBox3.Text = "文件名称： ";
                richTextBox3.Text += textBox1.Text;
                richTextBox3.Text += "\n";
                
                if (checkBox4.Enabled == true && checkBox4.Checked == true) //“CRC32”勾选
                {
                    richTextBox3.Text += "CRC32  ： ";
                    richTextBox3.Text += CRC32.GetFileCRC32(textBox1.Text);
                    richTextBox3.Text += "\n";
                }
                if (checkBox5.Enabled == true && checkBox5.Checked == true) //“MD5”勾选
                {
                    Stream fileStream = File.Open(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read);
                    long bufferSize = fileStream.Length / 1000; //将文件分为1000份，逐次读取
                    if (fileStream.Length % 1000 != 0)
                    {
                        bufferSize++;
                    }
                    byte[] inputBuffer  = new byte[bufferSize];
                    byte[] outputBuffer = new byte[bufferSize];
                    HashAlgorithm md5Algorithm = new MD5CryptoServiceProvider();
                    int readLength = 0;
                    while ((readLength = fileStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0)
                    {
                        //整个文件计算：md5Algorithm.ComputeHash(fileStream)
                        md5Algorithm.TransformBlock(inputBuffer, 0, readLength, outputBuffer, 0); //分段计算MD5
                        progressBar1.PerformStep();
                    }
                    md5Algorithm.TransformFinalBlock(inputBuffer, 0, 0);

                    richTextBox3.Text += "MD5    ： ";
                    richTextBox3.Text += BitConverter.ToString(md5Algorithm.Hash).Replace("-", "");
                    richTextBox3.Text += "\n";

                    md5Algorithm.Clear();
                    fileStream.Close();
                }
                if (checkBox6.Enabled == true && checkBox6.Checked == true) //“SHA1”勾选
                {
                    Stream fileStream = File.Open(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read);
                    long bufferSize = fileStream.Length / 1000; //将文件分为1000份，逐次读取
                    if (fileStream.Length % 1000 != 0)
                    {
                        bufferSize++;
                    }
                    byte[] inputBuffer = new byte[bufferSize];
                    byte[] outputBuffer = new byte[bufferSize];
                    HashAlgorithm sha1Algorithm = new SHA1CryptoServiceProvider();
                    int readLength = 0;
                    while ((readLength = fileStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0)
                    {
                        //整个文件计算：sha1Algorithm.ComputeHash(fileStream)
                        sha1Algorithm.TransformBlock(inputBuffer, 0, readLength, outputBuffer, 0); //分段计算MD5
                        progressBar1.PerformStep();
                    }
                    sha1Algorithm.TransformFinalBlock(inputBuffer, 0, 0);

                    richTextBox3.Text += "SHA1   ： ";
                    richTextBox3.Text += BitConverter.ToString(sha1Algorithm.Hash).Replace("-", "");
                    richTextBox3.Text += "\n";

                    sha1Algorithm.Clear();
                    fileStream.Close();
                }
            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            richTextBox1.Text = "";
            richTextBox2.Text = "";
            richTextBox3.Text = "";
            textBox1.Text = "";
            progressBar1.Value = 0;

            if (tabControl1.SelectedTab == tabPage1) //计算“十六进制字符串”
            {
                checkBox1.Enabled = true;  //累加和
                checkBox2.Enabled = true;  //异或和
                checkBox3.Enabled = true;  //CRC16
                checkBox4.Enabled = true;  //CRC32
                checkBox5.Enabled = true;  //MD5
                checkBox6.Enabled = true;  //SHA1
            }
            else if (tabControl1.SelectedTab == tabPage2) //计算“文件”
            {
                checkBox1.Enabled = false; //累加和
                checkBox2.Enabled = false; //异或和
                checkBox3.Enabled = false; //CRC16
                checkBox4.Enabled = true;  //CRC32
                checkBox5.Enabled = true;  //MD5
                checkBox6.Enabled = true;  //SHA1
            }
        }

        private void button3_Click(object sender, EventArgs e) //“清除”按钮
        {
            richTextBox1.Text = "";
            richTextBox2.Text = "";
            richTextBox3.Text = "";
            textBox1.Text = "";
            progressBar1.Value = 0;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            /* 设置窗口启动位置为上次关闭的位置 */
            try
            {
                RegistryKey reg = Registry.CurrentUser.CreateSubKey("SoftWare\\AlgorithmCalculator");
                object objectLocationX = reg.GetValue("LocationX");
                object objectLocationY = reg.GetValue("LocationY");
                if (objectLocationX != null && objectLocationY != null)
                {
                    this.Location = new Point(Convert.ToInt32(objectLocationX), Convert.ToInt32(objectLocationY));
                }
                else
                {
                    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
                }
            }
            catch (Exception)
            {
            }

            if (tabControl1.SelectedTab == tabPage1) //计算“十六进制字符串”
            {
                checkBox1.Enabled = true;  //累加和
                checkBox2.Enabled = true;  //异或和
                checkBox3.Enabled = true;  //CRC16
                checkBox4.Enabled = true;  //CRC32
                checkBox5.Enabled = true;  //MD5
                checkBox6.Enabled = true;  //SHA1
            }
            else if (tabControl1.SelectedTab == tabPage2) //计算“文件”
            {
                checkBox1.Enabled = false; //累加和
                checkBox2.Enabled = false; //异或和
                checkBox3.Enabled = false; //CRC16
                checkBox4.Enabled = true;  //CRC32
                checkBox5.Enabled = true;  //MD5
                checkBox6.Enabled = true;  //SHA1
            }


            IniFile iniFile = new IniFile();
            StringBuilder sb = new StringBuilder(250);

            if (Program.ArgsByMain.Length > 0)
            {
                tabControl1.SelectedTab = tabPage2;
                textBox1.Text = Program.ArgsByMain[0];
            }
            else
            {
                // 读取初始显示页面
                iniFile.GetIniString("AlgorithmCalculatorConfig", "ActiveTabPage", "", sb, sb.Capacity);
                string ActiveTabPage = sb.ToString();
                if (ActiveTabPage == "tabPage2")
                    tabControl1.SelectedTab = tabPage2;
                else
                    tabControl1.SelectedTab = tabPage1;
            }

            // 读取勾选框的选择状态
            iniFile.GetIniString("AlgorithmCalculatorConfig", "CheckBoxStatus", "", sb, sb.Capacity);
            char[] charSpilt = { ',' };
            string[] strStatus = sb.ToString().Split(charSpilt);
            if (strStatus.Length >= 1 && strStatus[0] == "1")
            {
                checkBox1.Checked = true;  //累加和
            }
            if (strStatus.Length >= 2 && strStatus[1] == "1")
            {
                checkBox2.Checked = true;  //异或和
            }
            if (strStatus.Length >= 3 && strStatus[2] == "1")
            {
                checkBox3.Checked = true;  //CRC16
            }
            if (strStatus.Length >= 4 && strStatus[3] == "1")
            {
                checkBox4.Checked = true;  //CRC32
            }
            if (strStatus.Length >= 5 && strStatus[4] == "1")
            {
                checkBox5.Checked = true;  //MD5
            }
            if (strStatus.Length >= 6 && strStatus[5] == "1")
            {
                checkBox6.Checked = true;  //SHA1
            }
        }

        private void tabPage2_DragDrop(object sender, DragEventArgs e)
        {
//             string[] files = null;
//             if (e.Data.GetDataPresent(DataFormats.FileDrop))
//             {
//                 files = e.Data.GetData(DataFormats.FileDrop) as string[];
//             }
            textBox1.Text = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
        }

        private void tabPage2_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            /* 存储窗口关闭的位置 */
            try
            {
                RegistryKey reg = Registry.CurrentUser.CreateSubKey("SoftWare\\AlgorithmCalculator");
                reg.SetValue("LocationX", this.Location.X);
                reg.SetValue("LocationY", this.Location.Y);
            }
            catch (Exception)
            {
            }

            IniFile iniFile = new IniFile();

            // 写入初始显示页面
            if (tabControl1.SelectedTab == tabPage1)
            {
                iniFile.WriteIniString("AlgorithmCalculatorConfig", "ActiveTabPage", "tabPage1");
            }
            else if (tabControl1.SelectedTab == tabPage2)
            {
                iniFile.WriteIniString("AlgorithmCalculatorConfig", "ActiveTabPage", "tabPage2");
            }

            // 写入勾选框的选择状态
            char[] byteStatus = { '0', ',', '0', ',', '0', ',', '0', ',', '0', ',', '0' };
            if (checkBox1.Checked == true) //累加和
            {
                byteStatus[0] = '1';
            }
            if (checkBox2.Checked == true) //异或和
            {
                byteStatus[2] = '1';
            }
            if (checkBox3.Checked == true) //CRC16
            {
                byteStatus[4] = '1';
            }
            if (checkBox4.Checked == true) //CRC32
            {
                byteStatus[6] = '1';
            }
            if (checkBox5.Checked == true) //MD5
            {
                byteStatus[8] = '1';
            }
            if (checkBox6.Checked == true) //SHA1
            {
                byteStatus[10] = '1';
            }
            string strStatus = new string(byteStatus);
            iniFile.WriteIniString("AlgorithmCalculatorConfig", "CheckBoxStatus", strStatus);
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            //当文本框中存在非十六进制字符时
            if (richTextBox1.Text != "" && !Regex.IsMatch(richTextBox1.Text, "^[0-9 A-Fa-f]+$"))
            {
                richTextBox1.Text = strHex;
                richTextBox1.Select(richTextBox1.TextLength, 0); //光标定位到最后
              //richTextBox1.ScrollToCaret(); //滚动到光标位置
                MessageBox.Show("输入的十六进制字符串中含有非法字符！");
            }
            else
            {
                strHex = richTextBox1.Text;
            }
        }

        private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsNumber(e.KeyChar) && e.KeyChar != (char)8 && !Regex.IsMatch(e.KeyChar.ToString(), "[0-9 A-Fa-f]"))
            {
                e.Handled = true;
            }
        }
    }
}
